package com.keqiang.chart.impl.pie.impl.pseudo3d

import android.graphics.Canvas
import android.graphics.Paint
import com.keqiang.chart.impl.pie.impl.normal.PieEntity
import com.keqiang.chart.utils.ObjectPool
import com.keqiang.chart.utils.draw3DArcBottom
import com.keqiang.chart.utils.draw3DArcShadow
import com.keqiang.chart.utils.draw3DArcTop
import com.keqiang.chart.utils.px
import com.keqiang.chart.utils.toRadian
import kotlin.math.cos
import kotlin.math.sin

/**
 * 饼状图高亮绘制器
 *
 * @author Created by wanggaowan on 2022/8/17 10:45
 */
open class PieChart3DHighLightRender constructor(chart: PieChart3D) : HighLightRender(chart) {

    /**
     * 高亮显示时的颜色
     */
    var highLightColor: HighLightColorFactory? = null

    /**
     * 高亮时半径增加的长度，中心点不发生偏移
     */
    var addedRadius: Float = 0f

    /**
     * 高亮时中心点向外移动的半径长度，不增加绘制的半径长度
     */
    var offsetRadius: Float = 20f.px
        set(value) {
            field = if (value < 0f) {
                0f
            } else {
                value
            }
        }

    override fun onDraw3D(canvas: Canvas, drawStartAngle: Float, drawSweepAngle: Float, data: PieEntity,
                          drawTop: Boolean, drawBottom: Boolean, drawShadowTop: Boolean, drawShadowBottom: Boolean) {
        val (centerX, centerY) = chart.getCenter()
        val radius = getRadius(data)
        val offset = getOffset(data)
        val color = highLightColor?.invoke(data) ?: data.color
        val flipAngle = chart.getDrawFlipAngle()
        val height = chart.getDrawHeight()
        val paint = ObjectPool.obtainPaint<Paint>()

        if (drawBottom) {
            canvas.draw3DArcBottom(paint, centerX, centerY + height, radius, chart.innerRadius, height,
                flipAngle, drawStartAngle, drawSweepAngle, color, offset.first, offset.second, chart.sliceSpace)
        }

        if (drawShadowTop) {
            canvas.draw3DArcShadow(paint, centerX, centerY + height, radius, height, flipAngle, drawStartAngle,
                drawSweepAngle, color, offset.first, offset.second, chart.sliceSpace, drawTop = true)
        }

        if (drawShadowBottom) {
            canvas.draw3DArcShadow(paint, centerX, centerY + height, radius, height, flipAngle, drawStartAngle,
                drawSweepAngle, color, offset.first, offset.second, chart.sliceSpace)
        }

        if (drawTop) {
            canvas.draw3DArcTop(paint, centerX, centerY, radius, chart.innerRadius, flipAngle, drawStartAngle,
                drawSweepAngle, color, offset.first, offset.second, chart.sliceSpace)
        }

        ObjectPool.recyclePaint(paint)
    }

    override fun getRadius(data: PieEntity): Float {
        return chart.radius + data.addedRadius + addedRadius
    }

    override fun getOffset(data: PieEntity): Pair<Float, Float> {
        if (offsetRadius <= 0) {
            return Pair(0f, 0f)
        }

        val centerRadian = (data.drawStartAngle + data.drawSweepAngle / 2f).toRadian
        return Pair(offsetRadius * cos(centerRadian), offsetRadius * sin(centerRadian))
    }
}

typealias HighLightColorFactory = (PieEntity) -> Int